home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GAS211S2.ZIP / src / gas-211 / opcodes / m68k-dis.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  24KB  |  971 lines

  1. /* Print Motorola 68k instructions.
  2.    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include "dis-asm.h"
  19. #include "ieee-float.h"
  20.  
  21. extern CONST struct ext_format ext_format_68881;
  22.  
  23. /* Opcode/m68k.h is a massive table.  As a kludge, break it up into
  24.    two pieces.  This makes nonportable C -- FIXME -- it assumes that
  25.    two data items declared near each other will be contiguous in
  26.    memory.  This kludge can be removed, FIXME, when GCC is fixed to not
  27.    be a hog about initializers.  */
  28.  
  29. #ifdef __GNUC__
  30. #define    BREAK_UP_BIG_DECL    }; \
  31.                 struct m68k_opcode m68k_opcodes_2[] = {
  32. #define    AND_OTHER_PART        sizeof (m68k_opcodes_2)
  33. #endif
  34.  
  35. #include "opcode/m68k.h"
  36.  
  37.  
  38. /* Local function prototypes */
  39.  
  40. static int
  41. fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
  42.  
  43. static void
  44. print_base PARAMS ((int, int, disassemble_info*));
  45.  
  46. static unsigned char *
  47. print_indexed PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
  48.  
  49. static unsigned char *
  50. print_insn_arg PARAMS ((char *, unsigned char *, unsigned char *, bfd_vma,
  51.             disassemble_info *));
  52.  
  53. /* Sign-extend an (unsigned char). */
  54. #if __STDC__ == 1
  55. #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
  56. #else
  57. #define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
  58. #endif
  59.  
  60. CONST char * CONST fpcr_names[] = {
  61.   "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
  62.   "fpiar/fpcr", "fpsr/fpcr", "fpiar/fpsr/fpcr"};
  63.  
  64. static char *reg_names[] = {
  65.   "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0",
  66.   "a1", "a2", "a3", "a4", "a5", "fp", "sp", "ps", "pc"};
  67.  
  68. /* Define accessors for 68K's 1, 2, and 4-byte signed quantities.
  69.    The _SHIFT values move the quantity to the high order end of an
  70.    `int' value, so it will sign-extend.  Probably a few more casts
  71.    are needed to make it compile without warnings on finicky systems.  */
  72. #define    BITS_PER_BYTE    8
  73. #define    WORD_SHIFT (BITS_PER_BYTE * ((sizeof (int)) - 2))
  74. #define    LONG_SHIFT (BITS_PER_BYTE * ((sizeof (int)) - 4))
  75.  
  76. #define NEXTBYTE(p)  (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
  77.  
  78. #define NEXTWORD(p)  \
  79.   (p += 2, FETCH_DATA (info, p), \
  80.    (((int)((p[-2] << 8) + p[-1])) << WORD_SHIFT) >> WORD_SHIFT)
  81.  
  82. #define NEXTLONG(p)  \
  83.   (p += 4, FETCH_DATA (info, p), \
  84.    (((int)((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])) \
  85.                    << LONG_SHIFT) >> LONG_SHIFT)
  86.  
  87. /* NEXTSINGLE and NEXTDOUBLE handle alignment problems, but not
  88.  * byte-swapping or other float format differences.  FIXME! */
  89.  
  90. union number {
  91.     double d;
  92.     float f;
  93.     char c[10];
  94. };
  95.  
  96. #define NEXTSINGLE(val, p) \
  97.   { int i; union number u;\
  98.     FETCH_DATA (info, p + sizeof (float));\
  99.     for (i = 0; i < sizeof(float); i++) u.c[i] = *p++; \
  100.     val = u.f; }
  101.  
  102. #define NEXTDOUBLE(val, p) \
  103.   { int i; union number u;\
  104.     FETCH_DATA (info, p + sizeof (double));\
  105.     for (i = 0; i < sizeof(double); i++) u.c[i] = *p++; \
  106.     val = u.d; }
  107.  
  108. /* Need a function to convert from extended to double precision... */
  109. #define NEXTEXTEND(p) \
  110.   (p += 12, FETCH_DATA (info, p), 0.0)
  111.  
  112. /* Need a function to convert from packed to double
  113.    precision.   Actually, it's easier to print a
  114.    packed number than a double anyway, so maybe
  115.    there should be a special case to handle this... */
  116. #define NEXTPACKED(p) \
  117.   (p += 12, FETCH_DATA (info, p), 0.0)
  118.  
  119.  
  120. /* Maximum length of an instruction.  */
  121. #define MAXLEN 22
  122.  
  123. #include <setjmp.h>
  124.  
  125. struct private
  126. {
  127.   /* Points to first byte not fetched.  */
  128.   bfd_byte *max_fetched;
  129.   bfd_byte the_buffer[MAXLEN];
  130.   bfd_vma insn_start;
  131.   jmp_buf bailout;
  132. };
  133.  
  134. /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
  135.    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
  136.    on error.  */
  137. #define FETCH_DATA(info, addr) \
  138.   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
  139.    ? 1 : fetch_data ((info), (addr)))
  140.  
  141. static int
  142. fetch_data (info, addr)
  143.      struct disassemble_info *info;
  144.      bfd_byte *addr;
  145. {
  146.   int status;
  147.   struct private *priv = (struct private *)info->private_data;
  148.   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
  149.  
  150.   status = (*info->read_memory_func) (start,
  151.                       priv->max_fetched,
  152.                       addr - priv->max_fetched,
  153.                       info);
  154.   if (status != 0)
  155.     {
  156.       (*info->memory_error_func) (status, start, info);
  157.       longjmp (priv->bailout, 1);
  158.     }
  159.   else
  160.     priv->max_fetched = addr;
  161.   return 1;
  162. }
  163.  
  164. static void
  165. m68k_opcode_error(info, code, place)
  166.      struct disassemble_info *info;
  167.      int code, place;
  168. {
  169.   (*info->fprintf_func)(info->stream,
  170.             "<internal error in opcode table: \"%c%c\">",
  171.             code, place);
  172. }
  173.  
  174. /* Print the m68k instruction at address MEMADDR in debugged memory,
  175.    on STREAM.  Returns length of the instruction, in bytes.  */
  176.  
  177. int
  178. print_insn_m68k (memaddr, info)
  179.      bfd_vma memaddr;
  180.      disassemble_info *info;
  181. {
  182.   register int i;
  183.   register unsigned char *p;
  184.   register char *d;
  185.   register unsigned long bestmask;
  186.   int best;
  187.   struct private priv;
  188.   bfd_byte *buffer = priv.the_buffer;
  189.  
  190.   info->private_data = (PTR) &priv;
  191.   priv.max_fetched = priv.the_buffer;
  192.   priv.insn_start = memaddr;
  193.   if (setjmp (priv.bailout) != 0)
  194.     /* Error return.  */
  195.     return -1;
  196.  
  197.   bestmask = 0;
  198.   best = -1;
  199.   FETCH_DATA (info, buffer + 2);
  200.   for (i = 0; i < numopcodes; i++)
  201.     {
  202.       register unsigned long opcode = m68k_opcodes[i].opcode;
  203.       register unsigned long match = m68k_opcodes[i].match;
  204.       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
  205.       && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
  206.       /* Only fetch the next two bytes if we need to.  */
  207.       && (((0xffff & match) == 0)
  208.           ||
  209.           (FETCH_DATA (info, buffer + 4)
  210.            && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
  211.            && ((0xff & buffer[3] & match) == (0xff & opcode)))
  212.           ))
  213.     {
  214.       /* Don't use for printout the variants of divul and divsl
  215.          that have the same register number in two places.
  216.          The more general variants will match instead.  */
  217.       for (d = m68k_opcodes[i].args; *d; d += 2)
  218.         if (d[1] == 'D')
  219.           break;
  220.  
  221.       /* Don't use for printout the variants of most floating
  222.          point coprocessor instructions which use the same
  223.          register number in two places, as above. */
  224.       if (*d == 0)
  225.         for (d = m68k_opcodes[i].args; *d; d += 2)
  226.           if (d[1] == 't')
  227.         break;
  228.  
  229.       if (*d == 0 && match > bestmask)
  230.         {
  231.           best = i;
  232.           bestmask = match;
  233.         }
  234.     }
  235.     }
  236.  
  237.   /* Handle undefined instructions.  */
  238.   if (best < 0)
  239.     {
  240.       (*info->fprintf_func) (info->stream, "0%o",
  241.                  (buffer[0] << 8) + buffer[1]);
  242.       return 2;
  243.     }
  244.  
  245.   (*info->fprintf_func) (info->stream, "%s", m68k_opcodes[best].name);
  246.  
  247.   /* Point at first word of argument data,
  248.      and at descriptor for first argument.  */
  249.   p = buffer + 2;
  250.   
  251.   /* Why do this this way? -MelloN */
  252.   for (d = m68k_opcodes[best].args; *d; d += 2)
  253.     {
  254.       if (d[0] == '#')
  255.     {
  256.       if (d[1] == 'l' && p - buffer < 6)
  257.         p = buffer + 6;
  258.       else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
  259.         p = buffer + 4;
  260.     }
  261.       if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)
  262.     p = buffer + 4;
  263.       if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)
  264.     p = buffer + 6;
  265.       if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
  266.     p = buffer + 4;
  267.     }
  268.   
  269.   FETCH_DATA (info, p);
  270.   
  271.   d = m68k_opcodes[best].args;
  272.  
  273.   if (*d)
  274.     (*info->fprintf_func) (info->stream, " ");
  275.  
  276.   while (*d)
  277.     {
  278.       p = print_insn_arg (d, buffer, p, memaddr + p - buffer, info);
  279.       d += 2;
  280.       if (*d && *(d - 2) != 'I' && *d != 'k')
  281.     (*info->fprintf_func) (info->stream, ",");
  282.     }
  283.   return p - buffer;
  284. }
  285.  
  286. static unsigned char *
  287. print_insn_arg (d, buffer, p, addr, info)
  288.      char *d;
  289.      unsigned char *buffer;
  290.      register unsigned char *p;
  291.      bfd_vma addr;        /* PC for this arg to be relative to */
  292.      disassemble_info *info;
  293. {
  294.   register int val = 0;
  295.   register int place = d[1];
  296.   int regno;
  297.   register CONST char *regname;
  298.   register unsigned char *p1;
  299.   double flval;
  300.   int flt_p;
  301.  
  302.   switch (*d)
  303.     {
  304.     case 'c':        /* cache identifier */
  305.       {
  306.         static char *cacheFieldName[] = { "NOP", "dc", "ic", "bc" };
  307.         val = fetch_arg (buffer, place, 2, info);
  308.         (*info->fprintf_func) (info->stream, cacheFieldName[val]);
  309.         break;
  310.       }
  311.  
  312.     case 'a':        /* address register indirect only. Cf. case '+'. */
  313.       {
  314.         (*info->fprintf_func)
  315.       (info->stream,
  316.        "%s@",
  317.        reg_names [fetch_arg (buffer, place, 3, info) + 8]);
  318.         break;
  319.       }
  320.  
  321.     case '_':        /* 32-bit absolute address for move16. */
  322.       {
  323.         val = NEXTLONG (p);
  324.         (*info->fprintf_func) (info->stream, "@#");
  325.     (*info->print_address_func) (val, info);
  326.         break;
  327.       }
  328.  
  329.     case 'C':
  330.       (*info->fprintf_func) (info->stream, "ccr");
  331.       break;
  332.  
  333.     case 'S':
  334.       (*info->fprintf_func) (info->stream, "sr");
  335.       break;
  336.  
  337.     case 'U':
  338.       (*info->fprintf_func) (info->stream, "usp");
  339.       break;
  340.  
  341.     case 'J':
  342.       {
  343.     static struct { char *name; int value; } names[]
  344.       = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
  345.          {"tc",  0x003}, {"itt0",0x004}, {"itt1", 0x005},
  346.              {"dtt0",0x006}, {"dtt1",0x007},
  347.          {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
  348.          {"msp", 0x803}, {"isp", 0x804}, {"mmusr",0x805},
  349.              {"urp", 0x806}, {"srp", 0x807}};
  350.  
  351.     val = fetch_arg (buffer, place, 12, info);
  352.     for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
  353.       if (names[regno].value == val)
  354.         {
  355.           (*info->fprintf_func) (info->stream, names[regno].name);
  356.           break;
  357.         }
  358.     if (regno < 0)
  359.       (*info->fprintf_func) (info->stream, "%d", val);
  360.       }
  361.       break;
  362.  
  363.     case 'Q':
  364.       val = fetch_arg (buffer, place, 3, info);
  365.       /* 0 means 8, except for the bkpt instruction... */
  366.       if (val == 0 && d[1] != 's')
  367.     val = 8;
  368.       (*info->fprintf_func) (info->stream, "#%d", val);
  369.       break;
  370.  
  371.     case 'M':
  372.       val = fetch_arg (buffer, place, 8, info);
  373.       if (val & 0x80)
  374.     val = val - 0x100;
  375.       (*info->fprintf_func) (info->stream, "#%d", val);
  376.       break;
  377.  
  378.     case 'T':
  379.       val = fetch_arg (buffer, place, 4, info);
  380.       (*info->fprintf_func) (info->stream, "#%d", val);
  381.       break;
  382.  
  383.     case 'D':
  384.       (*info->fprintf_func) (info->stream, "%s",
  385.                  reg_names[fetch_arg (buffer, place, 3, info)]);
  386.       break;
  387.  
  388.     case 'A':
  389.       (*info->fprintf_func)
  390.     (info->stream, "%s",
  391.      reg_names[fetch_arg (buffer, place, 3, info) + 010]);
  392.       break;
  393.  
  394.     case 'R':
  395.       (*info->fprintf_func)
  396.     (info->stream, "%s",
  397.      reg_names[fetch_arg (buffer, place, 4, info)]);
  398.       break;
  399.  
  400.     case 'r':
  401.       (*info->fprintf_func)
  402.     (info->stream, "%s@",
  403.      reg_names[fetch_arg (buffer, place, 4, info)]);
  404.       break;
  405.  
  406.     case 'F':
  407.       (*info->fprintf_func)
  408.     (info->stream, "fp%d",
  409.      fetch_arg (buffer, place, 3, info));
  410.       break;
  411.  
  412.     case 'O':
  413.       val = fetch_arg (buffer, place, 6, info);
  414.       if (val & 0x20)
  415.     (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]);
  416.       else
  417.     (*info->fprintf_func) (info->stream, "%d", val);
  418.       break;
  419.  
  420.     case '+':
  421.       (*info->fprintf_func)
  422.     (info->stream, "%s@+",
  423.      reg_names[fetch_arg (buffer, place, 3, info) + 8]);
  424.       break;
  425.  
  426.     case '-':
  427.       (*info->fprintf_func)
  428.     (info->stream, "%s@-",
  429.      reg_names[fetch_arg (buffer, place, 3, info) + 8]);
  430.       break;
  431.  
  432.     case 'k':
  433.       if (place == 'k')
  434.     (*info->fprintf_func)
  435.       (info->stream, "{%s}",
  436.        reg_names[fetch_arg (buffer, place, 3, info)]);
  437.       else if (place == 'C')
  438.     {
  439.       val = fetch_arg (buffer, place, 7, info);
  440.       if ( val > 63 )        /* This is a signed constant. */
  441.         val -= 128;
  442.       (*info->fprintf_func) (info->stream, "{#%d}", val);
  443.     }
  444.       else
  445.     m68k_opcode_error (info, *d, place);
  446.       break;
  447.  
  448.     case '#':
  449.     case '^':
  450.       p1 = buffer + (*d == '#' ? 2 : 4);
  451.       if (place == 's')
  452.     val = fetch_arg (buffer, place, 4, info);
  453.       else if (place == 'C')
  454.     val = fetch_arg (buffer, place, 7, info);
  455.       else if (place == '8')
  456.     val = fetch_arg (buffer, place, 3, info);
  457.       else if (place == '3')
  458.     val = fetch_arg (buffer, place, 8, info);
  459.       else if (place == 'b')
  460.     val = NEXTBYTE (p1);
  461.       else if (place == 'w')
  462.     val = NEXTWORD (p1);
  463.       else if (place == 'l')
  464.     val = NEXTLONG (p1);
  465.       else
  466.     m68k_opcode_error (info, *d, place);
  467.       (*info->fprintf_func) (info->stream, "#%d", val);
  468.       break;
  469.  
  470.     case 'B':
  471.       if (place == 'b')
  472.     val = NEXTBYTE (p);
  473.       else if (place == 'B')
  474.     val = COERCE_SIGNED_CHAR(buffer[1]);
  475.       else if (place == 'w' || place == 'W')
  476.     val = NEXTWORD (p);
  477.       else if (place == 'l' || place == 'L')
  478.     val = NEXTLONG (p);
  479.       else if (place == 'g')
  480.     {
  481.       val = NEXTBYTE (buffer);
  482.       if (val == 0)
  483.         val = NEXTWORD (p);
  484.       else if (val == -1)
  485.         val = NEXTLONG (p);
  486.     }
  487.       else if (place == 'c')
  488.     {
  489.       if (buffer[1] & 0x40)        /* If bit six is one, long offset */
  490.         val = NEXTLONG (p);
  491.       else
  492.         val = NEXTWORD (p);
  493.     }
  494.       else
  495.     m68k_opcode_error (info, *d, place);
  496.  
  497.       (*info->print_address_func) (addr + val, info);
  498.       break;
  499.  
  500.     case 'd':
  501.       val = NEXTWORD (p);
  502.       (*info->fprintf_func)
  503.     (info->stream, "%s@(%d)",
  504.      reg_names[fetch_arg (buffer, place, 3, info)], val);
  505.       break;
  506.  
  507.     case 's':
  508.       (*info->fprintf_func) (info->stream, "%s",
  509.                  fpcr_names[fetch_arg (buffer, place, 3, info)]);
  510.       break;
  511.  
  512.     case 'I':
  513.       /* Get coprocessor ID... */
  514.       val = fetch_arg (buffer, 'd', 3, info);
  515.       
  516.       if (val != 1)                /* Unusual coprocessor ID? */
  517.     (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
  518.       if (place == 'i')
  519.     p += 2;                 /* Skip coprocessor extended operands */
  520.       break;
  521.  
  522.     case '*':
  523.     case '~':
  524.     case '%':
  525.     case ';':
  526.     case '@':
  527.     case '!':
  528.     case '$':
  529.     case '?':
  530.     case '/':
  531.     case '&':
  532.     case '`':
  533.  
  534.       if (place == 'd')
  535.     {
  536.       val = fetch_arg (buffer, 'x', 6, info);
  537.       val = ((val & 7) << 3) + ((val >> 3) & 7);
  538.     }
  539.       else
  540.     val = fetch_arg (buffer, 's', 6, info);
  541.  
  542.       /* Get register number assuming address register.  */
  543.       regno = (val & 7) + 8;
  544.       regname = reg_names[regno];
  545.       switch (val >> 3)
  546.     {
  547.     case 0:
  548.       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
  549.       break;
  550.  
  551.     case 1:
  552.       (*info->fprintf_func) (info->stream, "%s", regname);
  553.       break;
  554.  
  555.     case 2:
  556.       (*info->fprintf_func) (info->stream, "%s@", regname);
  557.       break;
  558.  
  559.     case 3:
  560.       (*info->fprintf_func) (info->stream, "%s@+", regname);
  561.       break;
  562.  
  563.     case 4:
  564.       (*info->fprintf_func) (info->stream, "%s@-", regname);
  565.       break;
  566.  
  567.     case 5:
  568.       val = NEXTWORD (p);
  569.       (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
  570.       break;
  571.  
  572.     case 6:
  573.       p = print_indexed (regno, p, addr, info);
  574.       break;
  575.  
  576.     case 7:
  577.       switch (val & 7)
  578.         {
  579.         case 0:
  580.           val = NEXTWORD (p);
  581.           (*info->fprintf_func) (info->stream, "@#");
  582.           (*info->print_address_func) (val, info);
  583.           break;
  584.  
  585.         case 1:
  586.           val = NEXTLONG (p);
  587.           (*info->fprintf_func) (info->stream, "@#");
  588.           (*info->print_address_func) (val, info);
  589.           break;
  590.  
  591.         case 2:
  592.           val = NEXTWORD (p);
  593.           (*info->print_address_func) (addr + val, info);
  594.           break;
  595.  
  596.         case 3:
  597.           p = print_indexed (-1, p, addr, info);
  598.           break;
  599.  
  600.         case 4:
  601.           flt_p = 1;    /* Assume it's a float... */
  602.           switch( place )
  603.           {
  604.         case 'b':
  605.           val = NEXTBYTE (p);
  606.           flt_p = 0;
  607.           break;
  608.  
  609.         case 'w':
  610.           val = NEXTWORD (p);
  611.           flt_p = 0;
  612.           break;
  613.  
  614.         case 'l':
  615.           val = NEXTLONG (p);
  616.           flt_p = 0;
  617.           break;
  618.  
  619.         case 'f':
  620.           NEXTSINGLE(flval, p);
  621.           break;
  622.  
  623.         case 'F':
  624.           NEXTDOUBLE(flval, p);
  625.           break;
  626.  
  627.         case 'x':
  628.           ieee_extended_to_double (&ext_format_68881,
  629.                        (char *)p, &flval);
  630.           p += 12;
  631.           break;
  632.  
  633.         case 'p':
  634.           flval = NEXTPACKED(p);
  635.           break;
  636.  
  637.         default:
  638.           m68k_opcode_error (info, *d, place);
  639.           }
  640.           if ( flt_p )    /* Print a float? */
  641.         (*info->fprintf_func) (info->stream, "#%g", flval);
  642.           else
  643.         (*info->fprintf_func) (info->stream, "#%d", val);
  644.           break;
  645.  
  646.         default:
  647.           (*info->fprintf_func) (info->stream,
  648.                      "<invalid address mode 0%o>",
  649.                      (unsigned) val);
  650.         }
  651.     }
  652.       break;
  653.  
  654.     case 'L':
  655.     case 'l':
  656.     if (place == 'w')
  657.       {
  658.         char doneany;
  659.         p1 = buffer + 2;
  660.         val = NEXTWORD (p1);
  661.         /* Move the pointer ahead if this point is farther ahead
  662.            than the last.  */
  663.         p = p1 > p ? p1 : p;
  664.         if (val == 0)
  665.           {
  666.         (*info->fprintf_func) (info->stream, "#0");
  667.         break;
  668.           }
  669.         if (*d == 'l')
  670.           {
  671.         register int newval = 0;
  672.         for (regno = 0; regno < 16; ++regno)
  673.           if (val & (0x8000 >> regno))
  674.             newval |= 1 << regno;
  675.         val = newval;
  676.           }
  677.         val &= 0xffff;
  678.         doneany = 0;
  679.         for (regno = 0; regno < 16; ++regno)
  680.           if (val & (1 << regno))
  681.         {
  682.           int first_regno;
  683.           if (doneany)
  684.             (*info->fprintf_func) (info->stream, "/");
  685.           doneany = 1;
  686.           (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
  687.           first_regno = regno;
  688.           while (val & (1 << (regno + 1)))
  689.             ++regno;
  690.           if (regno > first_regno)
  691.             (*info->fprintf_func) (info->stream, "-%s",
  692.                        reg_names[regno]);
  693.         }
  694.       }
  695.     else if (place == '3')
  696.       {
  697.         /* `fmovem' insn.  */
  698.         char doneany;
  699.         val = fetch_arg (buffer, place, 8, info);
  700.         if (val == 0)
  701.           {
  702.         (*info->fprintf_func) (info->stream, "#0");
  703.         break;
  704.           }
  705.         if (*d == 'l')
  706.           {
  707.         register int newval = 0;
  708.         for (regno = 0; regno < 8; ++regno)
  709.           if (val & (0x80 >> regno))
  710.             newval |= 1 << regno;
  711.         val = newval;
  712.           }
  713.         val &= 0xff;
  714.         doneany = 0;
  715.         for (regno = 0; regno < 8; ++regno)
  716.           if (val & (1 << regno))
  717.         {
  718.           int first_regno;
  719.           if (doneany)
  720.             (*info->fprintf_func) (info->stream, "/");
  721.           doneany = 1;
  722.           (*info->fprintf_func) (info->stream, "fp%d", regno);
  723.           first_regno = regno;
  724.           while (val & (1 << (regno + 1)))
  725.             ++regno;
  726.           if (regno > first_regno)
  727.             (*info->fprintf_func) (info->stream, "-fp%d", regno);
  728.         }
  729.       }
  730.     else
  731.       goto de_fault;
  732.       break;
  733.  
  734.     default:  de_fault:
  735.       m68k_opcode_error (info, *d, ' ');
  736.     }
  737.  
  738.   return (unsigned char *) p;
  739. }
  740.  
  741. /* Fetch BITS bits from a position in the instruction specified by CODE.
  742.    CODE is a "place to put an argument", or 'x' for a destination
  743.    that is a general address (mode and register).
  744.    BUFFER contains the instruction.  */
  745.  
  746. static int
  747. fetch_arg (buffer, code, bits, info)
  748.      unsigned char *buffer;
  749.      int code;
  750.      int bits;
  751.      disassemble_info *info;
  752. {
  753.   register int val = 0;
  754.   switch (code)
  755.     {
  756.     case 's':
  757.       val = buffer[1];
  758.       break;
  759.  
  760.     case 'd':            /* Destination, for register or quick.  */
  761.       val = (buffer[0] << 8) + buffer[1];
  762.       val >>= 9;
  763.       break;
  764.  
  765.     case 'x':            /* Destination, for general arg */
  766.       val = (buffer[0] << 8) + buffer[1];
  767.       val >>= 6;
  768.       break;
  769.  
  770.     case 'k':
  771.       FETCH_DATA (info, buffer + 3);
  772.       val = (buffer[3] >> 4);
  773.       break;
  774.  
  775.     case 'C':
  776.       FETCH_DATA (info, buffer + 3);
  777.       val = buffer[3];
  778.       break;
  779.  
  780.     case '1':
  781.       FETCH_DATA (info, buffer + 3);
  782.       val = (buffer[2] << 8) + buffer[3];
  783.       val >>= 12;
  784.       break;
  785.  
  786.     case '2':
  787.       FETCH_DATA (info, buffer + 3);
  788.       val = (buffer[2] << 8) + buffer[3];
  789.       val >>= 6;
  790.       break;
  791.  
  792.     case '3':
  793.     case 'j':
  794.       FETCH_DATA (info, buffer + 3);
  795.       val = (buffer[2] << 8) + buffer[3];
  796.       break;
  797.  
  798.     case '4':
  799.       FETCH_DATA (info, buffer + 5);
  800.       val = (buffer[4] << 8) + buffer[5];
  801.       val >>= 12;
  802.       break;
  803.  
  804.     case '5':
  805.       FETCH_DATA (info, buffer + 5);
  806.       val = (buffer[4] << 8) + buffer[5];
  807.       val >>= 6;
  808.       break;
  809.  
  810.     case '6':
  811.       FETCH_DATA (info, buffer + 5);
  812.       val = (buffer[4] << 8) + buffer[5];
  813.       break;
  814.  
  815.     case '7':
  816.       FETCH_DATA (info, buffer + 3);
  817.       val = (buffer[2] << 8) + buffer[3];
  818.       val >>= 7;
  819.       break;
  820.       
  821.     case '8':
  822.       FETCH_DATA (info, buffer + 3);
  823.       val = (buffer[2] << 8) + buffer[3];
  824.       val >>= 10;
  825.       break;
  826.  
  827.     case '9':
  828.       FETCH_DATA (info, buffer + 3);
  829.       val = (buffer[2] << 8) + buffer[3];
  830.       val >>= 5;
  831.       break;
  832.  
  833.     case 'e':
  834.       val = (buffer[1] >> 6);
  835.       break;
  836.  
  837.     default:
  838.       abort ();
  839.     }
  840.  
  841.   switch (bits)
  842.     {
  843.     case 2:
  844.       return val & 3;
  845.     case 3:
  846.       return val & 7;
  847.     case 4:
  848.       return val & 017;
  849.     case 5:
  850.       return val & 037;
  851.     case 6:
  852.       return val & 077;
  853.     case 7:
  854.       return val & 0177;
  855.     case 8:
  856.       return val & 0377;
  857.     case 12:
  858.       return val & 07777;
  859.     default:
  860.       abort ();
  861.     }
  862. }
  863.  
  864. /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
  865.    P points to extension word, in buffer.
  866.    ADDR is the nominal core address of that extension word.  */
  867.  
  868. static unsigned char *
  869. print_indexed (basereg, p, addr, info)
  870.      int basereg;
  871.      unsigned char *p;
  872.      bfd_vma addr;
  873.      disassemble_info *info;
  874. {
  875.   register int word;
  876.   static char *scales[] = {"", "*2", "*4", "*8"};
  877.   register int base_disp;
  878.   register int outer_disp;
  879.   char buf[40];
  880.  
  881.   word = NEXTWORD (p);
  882.  
  883.   /* Generate the text for the index register.
  884.      Where this will be output is not yet determined.  */
  885.   sprintf (buf, "[%s.%c%s]",
  886.        reg_names[(word >> 12) & 0xf],
  887.        (word & 0x800) ? 'l' : 'w',
  888.        scales[(word >> 9) & 3]);
  889.  
  890.   /* Handle the 68000 style of indexing.  */
  891.  
  892.   if ((word & 0x100) == 0)
  893.     {
  894.       print_base (basereg,
  895.           ((word & 0x80) ? word | 0xff00 : word & 0xff)
  896.           + ((basereg == -1) ? addr : 0),
  897.           info);
  898.       (*info->fprintf_func) (info->stream, "%s", buf);
  899.       return p;
  900.     }
  901.  
  902.   /* Handle the generalized kind.  */
  903.   /* First, compute the displacement to add to the base register.  */
  904.  
  905.   if (word & 0200)
  906.     basereg = -2;
  907.   if (word & 0100)
  908.     buf[0] = 0;
  909.   base_disp = 0;
  910.   switch ((word >> 4) & 3)
  911.     {
  912.     case 2:
  913.       base_disp = NEXTWORD (p);
  914.       break;
  915.     case 3:
  916.       base_disp = NEXTLONG (p);
  917.     }
  918.   if (basereg == -1)
  919.     base_disp += addr;
  920.  
  921.   /* Handle single-level case (not indirect) */
  922.  
  923.   if ((word & 7) == 0)
  924.     {
  925.       print_base (basereg, base_disp, info);
  926.       (*info->fprintf_func) (info->stream, "%s", buf);
  927.       return p;
  928.     }
  929.  
  930.   /* Two level.  Compute displacement to add after indirection.  */
  931.  
  932.   outer_disp = 0;
  933.   switch (word & 3)
  934.     {
  935.     case 2:
  936.       outer_disp = NEXTWORD (p);
  937.       break;
  938.     case 3:
  939.       outer_disp = NEXTLONG (p);
  940.     }
  941.  
  942.   (*info->fprintf_func) (info->stream, "%d(", outer_disp);
  943.   print_base (basereg, base_disp, info);
  944.  
  945.   /* If postindexed, print the closeparen before the index.  */
  946.   if (word & 4)
  947.     (*info->fprintf_func) (info->stream, ")%s", buf);
  948.   /* If preindexed, print the closeparen after the index.  */
  949.   else
  950.     (*info->fprintf_func) (info->stream, "%s)", buf);
  951.  
  952.   return p;
  953. }
  954.  
  955. /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
  956.    REGNO = -1 for pc, -2 for none (suppressed).  */
  957.  
  958. static void
  959. print_base (regno, disp, info)
  960.      int regno;
  961.      int disp;
  962.      disassemble_info *info;
  963. {
  964.   if (regno == -2)
  965.     (*info->fprintf_func) (info->stream, "%d", disp);
  966.   else if (regno == -1)
  967.     (*info->fprintf_func) (info->stream, "0x%x", (unsigned) disp);
  968.   else
  969.     (*info->fprintf_func) (info->stream, "%d(%s)", disp, reg_names[regno]);
  970. }
  971.